import WebpackLicense from '@components/WebpackLicense';

<WebpackLicense from="https://webpack.js.org/plugins/define-plugin/" />

# DefinePlugin

The `DefinePlugin` replaces variables in your code with other values or expressions at compile time. This can be useful for allowing different behavior between development builds and production builds. If you perform logging in your development build but not in the production build you might use a global constant to determine whether logging takes place. That's where `DefinePlugin` shines, set it and forget it rules for development and production builds.

```js
new rspack.DefinePlugin({
  // Definitions...
});
```

## Options

- **Type:**

```ts
type CodeValue = RecursiveArrayOrRecord<CodeValuePrimitive>;
type CodeValuePrimitive =
  | null
  | undefined
  | RegExp
  | Function
  | string
  | number
  | boolean
  | bigint;
type RecursiveArrayOrRecord<T> =
  | { [index: string]: RecursiveArrayOrRecord<T> }
  | Array<RecursiveArrayOrRecord<T>>
  | T;

type DefinePluginOptions = Record<string, CodeValue>;
```

## Examples

### Basic use case

Each key passed into `DefinePlugin` is an identifier or multiple identifiers joined with `.`.

- If the value is a string it will be used as a code fragment.
- If the value isn't a string, it will be stringified (including functions).
- If the value is an object all keys are defined the same way.
- If you prefix `typeof` to the key, it's only defined for typeof calls.

The values will be inlined into the code allowing a minification pass to remove the redundant conditional.

```js
new rspack.DefinePlugin({
  PRODUCTION: JSON.stringify(true),
  VERSION: JSON.stringify('5fa3b9'),
  BROWSER_SUPPORTS_HTML5: true,
  TWO: '1+1',
  'typeof window': JSON.stringify('object'),
  'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
});
```

```js
console.log('Running App version ' + VERSION);
if (!BROWSER_SUPPORTS_HTML5) require('html5shiv');
```

:::warning
When defining values for `process` prefer `'process.env.NODE_ENV': JSON.stringify('production')` over `process: { env: { NODE_ENV: JSON.stringify('production') } }`. Using the latter will overwrite the `process` object which can break compatibility with some modules that expect other values on the process object to be defined.
:::

:::tip
Note that because the plugin does a direct text replacement, the value given to it must include **actual quotes** inside of the string itself. Typically, this is done either with alternate quotes, such as `'"production"'`, or by using `JSON.stringify('production')`.
:::

```js
if (!PRODUCTION) {
  console.log('Debug info');
}

if (PRODUCTION) {
  console.log('Production log');
}
```

After passing through Rspack with no minification results in:

```js
if (!true) {
  console.log('Debug info');
}
if (true) {
  console.log('Production log');
}
```

and then after a minification pass results in:

```js
console.log('Production log');
```

### Feature flags

Enable/disable features in production/development build using [feature flags](https://en.wikipedia.org/wiki/Feature_toggle).

```js
new rspack.DefinePlugin({
  NICE_FEATURE: JSON.stringify(true),
  EXPERIMENTAL_FEATURE: JSON.stringify(false),
});
```

### Service URLs

Use a different service URL in production/development builds:

```js
new rspack.DefinePlugin({
  SERVICE_URL: JSON.stringify('https://dev.example.com'),
});
```
